import argparse
import json
import os
import pathlib
import subprocess
import sys
from runModel import run_native_simulation
from util import init_log


def load_driver_config(config_path):
    cp = pathlib.Path(config_path)
    if not cp.is_absolute():
        cp = pathlib.Path(os.getcwd(), config_path)

    if not cp.is_file():
        raise Exception('driver.config "{}" not exists'.format(config_path))

    with open(cp, 'r') as f:
        config = json.load(f)
        if config.get('product') != 'abaqus':
            raise Exception('invalid driver.config')
        return config


def parse_model_parameters(args):
    logger.info('parse model: %s', args.model_dir)
    model_file = pathlib.Path(args.model_dir, args.entry)
    # 调用abaqus脚本解析参数
    if args.entry.endswith('inp'):
        cmd = f'abaqus python parseModelByInp.py {model_file} {args.output_file_path}'
    else:
        logger.info(f'unknow file suffix, {args.entry}')
        sys.exit(1)
    sp = subprocess.Popen(f'{cmd}', cwd=os.getcwd(), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
                          encoding='UTF-8')
    out_info, err_info = sp.communicate()
    logger.info(f'run out info: {out_info}', flush=True)
    logger.info(f'run err info: {err_info}', flush=True)


def run_simulation(args):
    with open(args.sim_config, 'r', encoding="utf-8") as file:
        sim_config = json.load(file)
    outputFilePath = args.output_file_path
    if outputFilePath:
        sim_config['outputFilePath'] = outputFilePath
    logger.info(sim_config)
    if sim_config['runMode'] == 'native':
        run_native_simulation(sim_config)


def main(args):
    global logger
    config = load_driver_config(args.driver_config)
    driver_cfg = config.get('config', {})
    logger = init_log(config=driver_cfg.get('log', {}))
    logger.info(args)

    # 运行模型 or 解析模型参数
    if args.subcommand == "run":
        return run_simulation(args)
    elif args.subcommand == "parse":
        return parse_model_parameters(args)
    else:
        raise Exception('invalid sub command')


if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='driver for abaqus')

    subparsers = parser.add_subparsers(title='Available Commands', dest="subcommand", help='sub-command is required')
    parser_run = subparsers.add_parser('run', help='run simulation')
    parser_run.add_argument('--driver-config', '-d', type=str, default='driver.config.json', help='driver config')
    parser_run.add_argument('--output-file-path', '-o', type=str, required=True, help='output file path')
    parser_run.add_argument('--sim-config', '-c', type=str, required=True, help='config for simulation task')

    parser_parse = subparsers.add_parser('parse', help='parse configurable parameters')
    parser_parse.add_argument('--output-file-path', '-o', type=str, required=True, help='output file path')
    parser_parse.add_argument('--driver-config', '-d', type=str, default='driver.config.json', help='driver config')
    parser_parse.add_argument('--model-dir', '-m', type=str, required=True, help='model dir')
    parser_parse.add_argument('--entry', '-e', type=str, required=True, help='model file')

    args_ = parser.parse_args()
    if not args_.subcommand:
        parser.print_help()
        sys.exit(1)
    sys.exit(main(args_))

